#pragma once

/// <summary>
/// ModelUtil: Methods for creating vertex/index buffers and AABB's based on passed
/// in ModelType arrays.
/// </summary>

/**	Author: Dane Bulat
  * Created: 06/2013
  * Last Modified: 30/06/2013
  * Version: v1.0
  */

// Includes
#include <D3D11.h>
#include <vector>
#include <fstream>

#include "common\xnacollision.h"
#include "common\MathHelper.h"
#include "common\d3dUtil.h"
#include "BasicShader.h"
using namespace std;

// ModelType struct
struct ModelType
{						// Stores vertex information from model txt file.
	float x, y, z;
	float tu, tv;
	float nx, ny, nz;
};

// Instanced Data struct
struct InstancedData
{						// Per-object data to be streamed to vertex shader.
	XMFLOAT4X4 World;
	XMFLOAT4   Color;
};

// Class Definition
class ModelUtil
{
public:
//==============================
// Constructors / Destructors
//==============================

	/// Default Constructor
	ModelUtil();

	/// Default Destructor
	~ModelUtil();

	/**
	  * Load Model from file
	  *
	  * @param File name
	  * @param Pointer to vector of model data to contain the vertices.
	  * @return Bool dependent on success/fail.
	  */
	static bool LoadModel(char* filename, vector<ModelType*>& modelData);


	/**
	  * Initialise the vertex buffer and collision box of a model.
	  *
	  * @param Pointer to D3D Device.
	  * @param Pointer to a vector of model data containing the model vertices.
	  * @param Pointer to an axis aligned box which will be set to the model dimensions.
	  * @return Pointer to initialised vertex buffer.
	  */
	static ID3D11Buffer* InitialiseVertexBuffer(ID3D11Device* device, vector<ModelType*>& modelData, XNA::AxisAlignedBox& modelAABB);

	/**
	  * Initialise the model index buffer.
	  *
	  * @param Pointer to D3D Device.
	  * @param Pointer to a vector of model data containing the model vertices.
	  * @return Pointer to initialised index buffer.
	  */
	static ID3D11Buffer* InitialiseIndexBuffer(ID3D11Device* device, vector<ModelType*>& modelData);

	/**
	  * Build an instanced buffer.
	  *
	  * @param Pointer to D3D Device.
	  * @param Pointer to a vector of instance data.
	  * @return Pointer to initialised instance buffer.
	  */
	static ID3D11Buffer* BuildInstancedBuffer(ID3D11Device* device, vector<InstancedData>& instancedData);

	/**
	  * Build a specific instanced buffer.
	  *
	  * @param Pointer to D3D Device.
	  * @param Pointer to a vector of instance data.
	  * @param String containing the mesh ID.
	  * @param String containing the instance map filename.
	  * @return Pointer to initialised instance buffer.
	  */
	 static ID3D11Buffer* BuildSpecificInstancedBuffer(ID3D11Device* device, vector<InstancedData>& instancedData, 
		const string& meshID, const string& mapFilename);
};